import * as THREE from '../../../../modules/three/three.module.js'
import {flatten} from "../util/StaticMethods.js";

const colorDefault = '#2665ff'
const unitZ = new THREE.Vector3(0, 0, 1)
const mtl = new THREE.MeshBasicMaterial({color: colorDefault, toneMapped: false})

// 用于自定义曲面网格 SurfaceGridPlugin
export default class DirPointIndicator extends THREE.Group {
  /**
   * @type {DirPointVO}
   */
  vo
  /**
   * @type {THREE.LineSegments}
   */
  segment
  /**
   * @type {THREE.LineSegments}
   */
  segPhi
  /**
   * @type {THREE.LineSegments}
   */
  segTheta

  constructor(vo) {
    super()
    this.vo = vo
    // const posAttr = new THREE.BufferAttribute(new Float32Array([0,0,0, 0,0,1]), 3)
    // const lineGeo = new THREE.BufferGeometry();
    // lineGeo.setAttribute('position', posAttr)
    const radius = 0.1;
    const origin = new THREE.Vector3(0, 0, 0);
    const pts = [origin];
    const faceIndices = [];
    const lineIndices = [];
    const segment = 6;
    const angle = (Math.PI * 2) / segment;
    for (let i = 0; i < segment; i++) {
      const a = angle * i;
      const x = radius * Math.sin(a);
      const y = radius * Math.cos(a);
      const pt = new THREE.Vector3(x, y, 0);
      pts.push(pt);
      if (i === segment - 1) {
        lineIndices.push(1, segment);
        // faceIndices.push(0, 1, segment);
      } else {
        lineIndices.push(i + 1, i + 2);
        // faceIndices.push(0, i + 2, i + 1);
      }
    }

    pts.push(new THREE.Vector3(0, 0, 1));
    lineIndices.push(0, segment + 1);

    const lineGeo = new THREE.BufferGeometry();
    lineGeo.setIndex(lineIndices);
    const posAttr = new THREE.BufferAttribute(flatten(pts), 3)
    lineGeo.setAttribute('position', posAttr);

    const seg = new THREE.LineSegments(lineGeo, mtl.clone())
    this.add(seg)
    this.segment = seg
    this.createSignalMeshes(0.15)
    this.syncByVO()
  }
  createSignalMeshes(radius) {
    const segments = 9
    const angle = Math.PI / (segments - 1)
    const above = 0.6
    const origin = new THREE.Vector3(0, 0, above);
    const pts = [origin];
    const faceIndices = [];
    const lineIndices = [];
    for (let i = 0; i < segments; i++) {
      const a = angle * i;
      const x = radius * Math.sin(a);
      const y = radius * Math.cos(a);
      const pt = new THREE.Vector3(x, y, above);
      pts.push(pt);
      if (i === segments - 1) {
        lineIndices.push(1, segments);
        faceIndices.push(0, 1, segments);
      } else {
        lineIndices.push(i + 1, i + 2);
        faceIndices.push(0, i + 2, i + 1);
      }
    }
    const lineGeo = new THREE.BufferGeometry();
    lineGeo.setIndex(lineIndices);
    const posAttr = new THREE.BufferAttribute(flatten(pts), 3)
    lineGeo.setAttribute('position', posAttr);
    const segPhi = new THREE.LineSegments(lineGeo, mtl.clone())
    const segTheta = segPhi.clone()

    const geometry = new THREE.BufferGeometry()
    geometry.setIndex(faceIndices)
    geometry.setAttribute('position', posAttr)
    const meshPhi = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({color: '#0f6e22'}))
    const meshTheta = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({color: '#ff6000'}))
    meshTheta.rotation.z = Math.PI
    segPhi.add(meshPhi)
    segTheta.add(meshTheta)
    this.add(segPhi, segTheta)
    segPhi.visible = segTheta.visible = false
    this.segPhi = segPhi
    this.segTheta = segTheta
  }
  toggleAdhered(adhered) {
    this.segment.material.color.setStyle(adhered ? '#0b4' : colorDefault)
  }
  updateVO() {
    this.vo.position.copy(this.position)
    this.vo._normal.copy(unitZ).applyQuaternion(this.quaternion)
  }
  syncByVO() {
    this.position.copy(this.vo.position)
    this.quaternion.setFromUnitVectors(unitZ, this.vo._normal)
  }
  toggleSegPhiVisible(visible) {
    this.segPhi.visible = visible
  }
  toggleSegThetaVisible(visible) {
    this.segTheta.visible = visible
  }
  _colorSignal(seg, cssColorStr) {
    seg.children[0].material.color.setStyle(cssColorStr)
    seg.visible = true
  }
  colorPhi(cssColor) {
    this._colorSignal(this.segPhi, cssColor)
  }
  colorTheta(cssColor) {
    this._colorSignal(this.segTheta, cssColor)
  }
}
